package gscrapper.service;

import gscrapper.entity.NintendoGameInfo;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

public class NintendoService {
	private static final String LOGIN_URL = "https://club.nintendo.com/api/authentication/login";
	private static final String REFERRER_URL = "https://club.nintendo.com/home.do";
	private static final String LIST_URL = "https://club.nintendo.com/account.do";

	static {
		// http://stackoverflow.com/questions/7744075/how-to-connect-via-https-using-jsoup
		// keytool -import -v -file /path/to/file.crt -keystore
		// /path/to/file.jks -storepass guessit
		System.setProperty("javax.net.ssl.trustStore", "*.nintendo.com.jks");
	}

	private Map<String, String> signIn(String username, String password) {
		System.out.println("Signing in...");
		try {
			Response response = Jsoup.connect(LOGIN_URL) //
					.data("username", username) //
					.data("password", password) //
					.referrer(REFERRER_URL).method(Method.POST) //
					.timeout(0) //
					.execute();
			System.out.println("Logged in");

			return response.cookies();
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	private String locateListTableEntry() {
		return "div#products.tab-content.four div.module table tbody tr";
	}

	private String locateGameInfo(int row, int column) {
		return String.format("%s:eq(%d) td:eq(%d)", locateListTableEntry(),
				row, column);
	}

	private String getElementText(Document doc, String cssQuery) {
		Elements list = doc.select(cssQuery);
		return (list.isEmpty() ? "" : list.get(0).text());
	}

	private String locateTitle(int row) {
		return locateGameInfo(row, 0);
	}

	private String locateRegistered(int row) {
		return locateGameInfo(row, 1);
	}

	public List<NintendoGameInfo> scrapp(String username, String password) {
		List<NintendoGameInfo> list = new ArrayList<NintendoGameInfo>();

		try {
			DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy",
					Locale.US);

			Map<String, String> cookies = signIn(username, password);

			System.out.println("Loading page...");
			Document doc = Jsoup.connect(LIST_URL).referrer(REFERRER_URL)
					.cookies(cookies).timeout(0).get();

			for (int row = 0; row < doc.select(locateListTableEntry()).size(); row++) {
				NintendoGameInfo game = new NintendoGameInfo();

				game.setTitle(getElementText(doc, locateTitle(row)));
				game.setRegistered(dateFormat.parse(getElementText(doc,
						locateRegistered(row))));
				list.add(game);
			}

		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return list;
	}
}
